#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

#define BUFFER_SIZE 1024

void* receive_messages(void* arg) 
{
    int client_fd = *(int*)arg;
    char buffer[BUFFER_SIZE];    
    while (1) 
    {
        ssize_t bytes_received = recv(client_fd, buffer, BUFFER_SIZE, 0);
        if (bytes_received <= 0) 
        {
            std::cerr << "\033[31m" << "客户端与服务端连接关闭或出现了其他错误" << "\033[0m" << std::endl;
            break;
        }
        buffer[bytes_received] = '\0';
        std::cerr << "\033[33m" << buffer << "\033[0m" << std::endl;
    }
    return nullptr;
}

std::vector<std::string> split(const std::string& str, char skip)
{
    std::vector<std::string> ans = std::vector<std::string>();
    std::string assist = std::string();
    for (auto ch : str)
    {
        if (ch == skip)
        {
            if (!assist.empty())
            {
                ans.push_back(assist);
                assist.clear();
            }
        }
        else
        {
            assist += ch;
        }
    }
    if (!assist.empty())
    {
        ans.push_back(assist);
    }
    return ans;
}

int main(int argc, char* argv[]) 
{
    if (argc == 2 && std::string(argv[0]) == "--help")
    {
        std::cerr << "\033[32m" << "功能：" << "\033[0m" << std::endl;
        std::cerr << "  " << "作为客户端连接到一个指定的服务端" << std::endl;
        std::cerr << "\033[32m" << "用法：" << "\033[0m" << std::endl;
        std::cerr << "  " << "client [选项|参数]" << std::endl;
        std::cerr << "\033[32m" << "选项：" << "\033[0m" << std::endl;
        std::cerr << "  " << "--help" << std::endl;
        std::cerr << "    " << "输出帮助文档" << std::endl;
        std::cerr << "\033[32m" << "参数：" << "\033[0m" << std::endl;
        std::cerr << "  " << "一个字符串" << std::endl;
        std::cerr << "    " << "<host>:<port>形式的字符串, <host>为点分十进制表示的服务端IPV4地址, <port>为服务端的端口号" << std::endl;
        return 0;
    }
    if (argc <= 1)
    {
        std::cerr << "\033[31m" << "请输入参数或选项, 可通过\"client --help\"查看帮助文档" << "\033[0m" << std::endl;
        return 1;
    }
    if (argc == 2)
    {
        std::string host_port_string = std::string(argv[1]);
        std::vector<std::string> host_port = split(host_port_string, ':');
        std::uint16_t port = 0;
        try
        {
            port = std::stoi(host_port[1]);
        }
        catch(const std::exception&)
        {
            std::cerr << "\033[31m" << "无法从参数中获取无符号16位整数作为端口号" << "\033[0m" << std::endl;
            return 1;
        }
        int client_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (client_fd < 0) 
        {
            std::cerr << "\033[31m" << "客户端创建套接字失败" << "\033[0m" << std::endl;
            return 1;
        }
        sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(port);
        inet_pton(AF_INET, host_port[0].c_str(), &server_addr.sin_addr);
        std::cerr << "\033[33m" << "目的ip: " << "\033[34m" << host_port[0] << "\033[33m" << " 目的port: " << "\033[34m" << port << "\033[0m" << std::endl;
        if (connect(client_fd, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) 
        {
            std::cerr << "\033[31m" << "客户端连接服务端失败" << "\033[0m" << std::endl;
            return 1;
        }
        std::cout << "\033[32m" << "客户端成功连接到服务端" << "\033[0m" << std::endl;
        pthread_t thread;
        pthread_create(&thread, nullptr, receive_messages, &client_fd);
        pthread_detach(thread);
        char buffer[BUFFER_SIZE];
        while (true) 
        {
            std::cin.getline(buffer, BUFFER_SIZE);
            send(client_fd, buffer, strlen(buffer), 0);
            if (std::string(buffer) == "exit")
            {
                std::cerr << "\033[33m" << "断开与服务器的连接" << "\033[0m" << std::endl;
                break;
            }
        }
        close(client_fd);
    }
    return 0;
}